package com.example.student_manager_backend.entity;

import com.example.student_manager_backend.status.CourseStatus;
import jakarta.persistence.*;
import lombok.Setter;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * 课程实体类
 * 存储课程基本信息及与学生的多对多关联关系
 */
@Entity
@Table(name = "course")
public class Course {

    /** 课程编号（主键） */
    @Setter
    @Id
    @Column(length = 20, nullable = false, unique = true)
    private String courseId;

    /** 课程名称（非空） */
    @Setter
    @Column(nullable = false, length = 100)
    private String name;

    /** 学分 */
    @Setter
    private Float credit;

    /** 学时 */
    @Setter
    private Integer hours;

    /** 课程类型（如必修、选修） */
    @Setter
    @Column(length = 20)
    private String type;

    /** 课程描述 */
    @Setter
    @Column(length = 500)
    private String description;

    /** 课程状态（枚举类型，默认开课中） */
    @Setter
    @Enumerated(EnumType.STRING)
    @Column(length = 20, nullable = false)
    private CourseStatus status = CourseStatus.ACTIVE;
    /**
     * 课程最大容量
     */
    @Setter
    private Integer maxCapacity;

    /** 创建时间（自动填充） */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false, updatable = false)
    private Date createTime;

    /** 更新时间（自动填充） */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Date updateTime;


    /**
     * 多对多关联：选修该课程的学生（双向关联）
     * - fetch = FetchType.LAZY：延迟加载，提高性能
     * - cascade = CascadeType.PERSIST：级联保存学生选课记录
     * - @JoinTable：指定关联表名及外键
     */
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @JoinTable(
            name = "student_course", // 关联表名
            joinColumns = @JoinColumn(name = "course_id", referencedColumnName = "courseId"), // 课程外键
            inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "studentId") // 学生外键
    )
    private Set<Student> students = new HashSet<>(); // 使用 HashSet 自动去重

    // 构造方法 & Getter/Setter

    public Course() {
        // 无参构造（JPA 要求）
    }

    public Course(String courseId, String name, Float credit, Integer hours, String type,Integer maxCapacity) {
        this.courseId = courseId;
        this.name = name;
        this.credit = credit;
        this.hours = hours;
        this.type = type;
        this.maxCapacity = maxCapacity;
    }

    // Getter 和 Setter 省略部分代码，仅展示核心字段
    public String getCourseId() {
        return courseId;
    }

    public String getName() {
        return name;
    }


    public Float getCredit() {
        return credit;
    }

    public Integer getHours() {
        return hours;
    }
    public Integer getMaxCapacity(){
        return maxCapacity;
    }

    public String getType() {
        return type;
    }

    public String getDescription() {
        return description;
    }

    public CourseStatus getStatus() {
        return status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public Set<Student> getStudents() {
        return students;
    }



    // 业务方法（封装关联操作）


    /**
     * 添加学生选课记录（维护双向关联）
     * @param student 学生实体
     */
    public void addStudent(Student student) {
        students.add(student);
        student.getCourses().add(this); // 调用学生的 addCourse 方法
    }

    /**
     * 移除学生选课记录（维护双向关联）
     * @param student 学生实体
     */
    public void removeStudent(Student student) {
        students.remove(student);
        student.getCourses().remove(this); // 调用学生的 removeCourse 方法
    }

    /**
     * 获取已选学生数量
     * @return 学生数量
     */
    public int getStudentCount() {
        return students.size();
    }

    // ========================
    // JPA 回调（自动填充时间）
    // ========================

    @PrePersist
    protected void onCreate() {
        Date now = new Date();
        createTime = now;
        updateTime = now;
    }

    @PreUpdate
    protected void onUpdate() {
        updateTime = new Date();
    }
}